//
//  MFWDownloadTaskRequest.m
//  download
//
//  Created by 陈曦 on 13-4-26.
//  Copyright (c) 2013年 陈曦. All rights reserved.
//

#import "MFWDownloadTaskRequest.h"
#import "MFWDownloadHeadChecker.h"
#ifndef MFWSdkHeaders
#import "ASIHTTPRequest.h"
#import "ASINetworkQueue.h"
#endif
#import "MFWDownloadHttpRequest.h"

@interface MFWDownloadTaskRequest()<ASIHTTPRequestDelegate>

@property (nonatomic, copy)   NSString                              *url;
@property (nonatomic, retain) MFWDownloadHttpRequest                *request;
@property (nonatomic, retain) NSMutableData                         *data;

@property (nonatomic, assign) NSInteger                             retryCount;
@property (nonatomic, assign) id<MFWDownloadTaskRequestDelegate>    delegate;

@end

@implementation MFWDownloadTaskRequest

- (unsigned long long)unDownloadSize
{
    return self.length - self.data.length;
}

- (BOOL)isRunning
{
    return (self.request != nil);
}

- (void)flush
{
    if(self.data && self.data.length > 0)
    {
        [self.delegate taskRequest:self getData:self.data atOffset:self.beginOffset];
        self.data = [[NSMutableData alloc] init];
    }
}

// 结束 两种调用方式  第一 request正常返回数据结果  第二 如果更改了length 则中断requet
- (void)didFinish
{
    [self flush];
    [self.delegate taskRequestFinished:self];
}

- (void)didFailWithErrorNSString:(NSString*)aErrorStr
{
//    [TGMClickHelper eventDownloadTaskRequestError:aErrorStr
//                                              url:self.request.url.absoluteString
//                                      requestHead:[MFWJsonUtils stringEncodingJsonObject:self.request.requestHeaders]
//                                     responseHead:[MFWJsonUtils stringEncodingJsonObject:self.request.responseHeaders]];
    
    [self stop];
    [self.delegate taskRequestFailed:self];
}

- (id)initWithUrl:(NSString *)aUrl delegate:(id<MFWDownloadTaskRequestDelegate>)aDelegate
{
    self = [super init];
    if (self)
    {
        self.url = aUrl;
        self.bufferSize = 1024 * 100;
        self.length = 0;
        self.beginOffset = 0;
        self.retryCount = 0;
        self.delegate = aDelegate;
    }
    return self;
}

- (void)start
{
    [self start:self.url];
}

- (void)start:(NSString*)aUrl
{    
    self.retryCount++;
    self.data = [[NSMutableData alloc] init];
    if (self.request)
    {
        [self.request clearDelegatesAndCancel];
        self.request = nil;
    }
    MFWDownloadHttpRequest *request = [[MFWDownloadHttpRequest alloc] initWithURL:[NSURL URLWithString:aUrl]];
    request.shouldContinueWhenAppEntersBackground = YES;
    [request setAllowCompressedResponse:NO];
    [request setShouldCompressRequestBody:NO];
    self.request = request;
    self.request.delegate = self;
    NSString *value = [NSString stringWithFormat:@"bytes=%lld - %lld",self.beginOffset,self.beginOffset + self.length - 1];
    [self.request addRequestHeader:@"Range" value:value];
    [self.request startAsynchronous];
}

- (void)request:(MFWDownloadHttpRequest *)request didReceiveResponseHeaders:(NSDictionary *)responseHeaders
{
    MFWDownloadHeadChecker *check = [MFWDownloadHeadChecker checkWithHeadDict:responseHeaders];
    if (check.redirectUrl.length)
    {
        [request clearDelegatesAndCancel];
        [self start:check.redirectUrl];
        return;
    }
    
    if (check.beginOffset != self.beginOffset || check.curLength < self.length)
    {
        if (self.beginOffset != 0 || self.length != 0)
        {
            NSString *string = [NSString stringWithFormat:@"预期开始:%lld 长度:%lld ",self.beginOffset,self.length];
            [self didFailWithErrorNSString:string];
        }
    }
}

- (void)request:(MFWDownloadHttpRequest*)request didReceiveData:(NSData *)aData
{
    if (request.willRedirect)
    {
        return;
    }
    [self.data appendData:aData];
    self.retryCount = 0;
    if (self.length != 0 && self.data.length >= self.length)
    {
        [request clearDelegatesAndCancel];
        [self didFinish];
    }
    else if(self.data.length > self.bufferSize)
    {
        [self flush];
    }
    else
    {
        // do nothing
    }
}

- (void)dealloc
{
    [self stop];
}

- (void)requestFailed:(ASIHTTPRequest*)request
{
    [self didFailWithErrorNSString:request.error.description];
}

- (void)requestFinished:(ASIHTTPRequest* __unused)request
{
    if (self.length == 0 ||
        (self.length != 0 && self.data.length >= self.length))
    {
        [self didFinish];
    }
    else
    {
        [self start];
    }
}

- (void)stop
{
    [self flush];
    [self.request clearDelegatesAndCancel];
    self.request = nil;
}

- (void)clear
{
    [self.request clearDelegatesAndCancel];
    self.request = nil;
    self.data = nil;
}

@end
